﻿#include "dma.h"


/**
 * @brief ADC0的DMA配置
 * @param adcValue 存放采集结果的缓冲区指针
 * @param length 缓冲区的长度
 */
void Dma0ConfigForAdc0(uint16_t *adcValue, uint8_t length)
{
    /* ADC_DMA_channel configuration */
    dma_parameter_struct dma_data_parameter;

    /* enable DMA0 clock */
    rcu_periph_clock_enable(RCU_DMA0);

    /* ADC DMA_channel configuration */
    dma_deinit(DMA0, DMA_CH0);

    /* initialize DMA single data mode */
    dma_data_parameter.periph_addr  = (uint32_t)(&ADC_RDATA(ADC0));
    dma_data_parameter.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
    dma_data_parameter.memory_addr  = (uint32_t)(adcValue);
    dma_data_parameter.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
    dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_16BIT;
    dma_data_parameter.direction    = DMA_PERIPHERAL_TO_MEMORY;
    dma_data_parameter.number       = (uint32_t)length;
    dma_data_parameter.priority     = DMA_PRIORITY_HIGH;
    dma_init(DMA0, DMA_CH0, &dma_data_parameter);
    dma_circulation_enable(DMA0, DMA_CH0);

    dma_interrupt_enable(DMA0, DMA_CH0, DMA_INT_FTF);
    dma_interrupt_enable(DMA0, DMA_CH0, DMA_INT_HTF);
    nvic_irq_enable(DMA0_Channel0_IRQn, 6, 0);

    /* enable DMA channel */
    dma_channel_enable(DMA0, DMA_CH0);
}

/**
 * @brief ADC0采集值转储
 * @param src 源地址
 * @param des 目的地址
 * @param length 转移数据长度
 */
void Dma0ConfigForAdcDump(uint16_t *src, uint16_t *des, uint8_t length)
{
    /* ADC_DMA_channel configuration */
    dma_parameter_struct dma_data_parameter;

    /* enable DMA0 clock */
    rcu_periph_clock_enable(RCU_DMA0);

    /* ADC DMA_channel configuration */
    dma_deinit(DMA0, DMA_CH3);

    /* initialize DMA single data mode */
    dma_data_parameter.periph_addr  = (uint32_t)(src);
    dma_data_parameter.periph_inc   = DMA_PERIPH_INCREASE_ENABLE;
    dma_data_parameter.memory_addr  = (uint32_t)(des);
    dma_data_parameter.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
    dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_16BIT;
    dma_data_parameter.direction    = DMA_PERIPHERAL_TO_MEMORY;
    dma_data_parameter.number       = (uint32_t)length;
    dma_data_parameter.priority     = DMA_PRIORITY_HIGH;
    dma_init(DMA0, DMA_CH3, &dma_data_parameter);
    dma_circulation_disable(DMA0, DMA_CH3);

    dma_memory_to_memory_enable(DMA0, DMA_CH3);

    dma_interrupt_enable(DMA0, DMA_CH3, DMA_INT_FTF);
    nvic_irq_enable(DMA0_Channel3_IRQn, 5, 0);

    /* enable DMA channel */
    // dma_channel_enable(DMA0, DMA_CH3);
}

/**
 * @brief TIMER0的DMA配置
 * @param memAddr
 * @param length
 */
void Dma0ConfigForTimer0(uint16_t *freqBuffer, uint16_t *dutyBuffer)
{
    dma_parameter_struct dma_init_struct;

    /* enable DMA clock */
    rcu_periph_clock_enable(RCU_DMA0);

    /* initialize DMA channel 1 */
    dma_deinit(DMA0, DMA_CH1);

    /* DMA channel 1 initialize */
    dma_init_struct.direction    = DMA_PERIPHERAL_TO_MEMORY;
    dma_init_struct.memory_addr  = (uint32_t)freqBuffer;
    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_DISABLE;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
    dma_init_struct.number       = 1;
    dma_init_struct.periph_addr  = (uint32_t)&TIMER_CH0CV(TIMER0);
    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH;
    dma_init(DMA0, DMA_CH1, &dma_init_struct);

    /* DMA0 channel 1 mode configuration */
    dma_circulation_enable(DMA0, DMA_CH1);
    dma_memory_to_memory_disable(DMA0, DMA_CH1);

    /* initialize DMA channel 2 */
    dma_deinit(DMA0, DMA_CH2);

    /* DMA channel 2 initialize */
    dma_init_struct.direction    = DMA_PERIPHERAL_TO_MEMORY;
    dma_init_struct.memory_addr  = (uint32_t)dutyBuffer;
    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_DISABLE;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
    dma_init_struct.number       = 1;
    dma_init_struct.periph_addr  = (uint32_t)&TIMER_CH1CV(TIMER0);
    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH;
    dma_init(DMA0, DMA_CH2, &dma_init_struct);

    /* DMA0 channel 2 mode configuration */
    dma_circulation_enable(DMA0, DMA_CH2);
    dma_memory_to_memory_disable(DMA0, DMA_CH2);

    /* enable DMA0 transfer */
    dma_channel_enable(DMA0, DMA_CH1);
    dma_channel_enable(DMA0, DMA_CH2);
}
